<template>
  <div>
<!--   设置栏目 -->
    <el-row :gutter="0" type="flex" class="row-bg" justify="start">
      <el-col span="4">
        <el-switch
          class="grid-content"
          active-text="批量删除"
          v-model="batchDelete"
          active-color="#13ce66"
          inactive-color="#565656">
        </el-switch>
      </el-col>
      <el-col span="4">
        <el-switch
          class="grid-content"
          active-text="拖动修改"
          v-model="treeDraggable"
          active-color="#13ce66"
          inactive-color="#565656">
        </el-switch>
      </el-col>
      <el-col span="10" >
        <el-button type="danger" :disabled="!batchDelete||idsToBatchDeletel.length<=0" size="mini" round @click="batchDeleteCatByIds">删除所选项</el-button>
        <el-button type="danger" :disabled="!treeDraggable||!batchDragUpdate||!catTreeDataChanged" size="mini" round @click="cancleDraggedTree">放弃拖动修改</el-button>
        <el-button type="primary" :disabled="!treeDraggable||!batchDragUpdate||!catTreeDataChanged" size="mini" round @click="batchPermanentDraggedCats">应用拖动修改</el-button>
      </el-col>
      <el-col span="6" >
        <el-switch
          :disabled="treeDraggable==false"
          class="grid-content"
          active-text="拖动后暂存不应用修改"
          inactive-text="拖动后立即应用修改"
          v-model="batchDragUpdate"
          active-color="#13ce66"
          inactive-color="#565656">
        </el-switch>
      </el-col>


    </el-row>

    <el-tree
      :data="catTrees"
      node-key="catId"
      :props="defaultProps"
      :show-checkbox="batchDelete"
      :aria-expanded="expandedCats"
      :draggable="treeDraggable"
      :allow-drop="allowDrop"
      :allow-drag="allowDrag"
      @node-drag-start="handleDragStart"
      @node-drag-enter="handleDragEnter"
      @node-drag-leave="handleDragLeave"
      @node-drag-over="handleDragOver"
      @node-drag-end="handleDragEnd"
      @node-drop="handleDrop"
      @check-change="handleCheckChange">
       <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ node.label }}</span>
        <span>
           <el-button
             type="text"
             size="mini"
             @click="() => remove(node, data)">
            Del
          </el-button>
          <el-button v-if="isNodeInThirdLeve(node,data)==false"
                     type="text"
                     size="mini"
                     @click="() => append(node,data)">
            addCat
          </el-button>
          <el-button
            type="text"
            size="mini"
            @click="() => editCatNode(node,data)">
             edit
          </el-button>
        </span>
      </span>
    </el-tree>

    <el-dialog title="新增分类" :visible.sync="addCatDialogFormVisible">
          <el-form :model="toAddCat">
            catId 数据库自动生成
            <el-form-item label="分类名称" :label-width="formLabelWidth">
              <el-input v-model="toAddCat.name" autocomplete="off"></el-input>
            </el-form-item>1
            <!--       父分类id自动填充  -->
            <!--          层级自动填充-->
            <el-form-item label="父分类" :label-width="formLabelWidth">
              <el-cascader
                v-model="addCatCascaderselectedOptions"
                :options="catTreesCanBeParent"
                :props="cascaderProps"
                @change="handleAddChange"
                :show-all-levels="false"
                expand-trigger="hover"
                change-on-select
                clearable>
              </el-cascader>
            </el-form-item>
            <el-form-item label="是否显示 [0-不显示，1显示]" :label-width="formLabelWidth">
              <el-input v-model="toAddCat.showStatus" autocomplete="off" type="number" min="0" max="1" ></el-input>
            </el-form-item>
            <el-form-item label="排序" :label-width="formLabelWidth" type="number">
              <el-input v-model="toAddCat.sort" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="图标" :label-width="formLabelWidth">
              <el-input v-model="toAddCat.icon" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="计量单位" :label-width="formLabelWidth">
              <el-input v-model="toAddCat.productUnit" autocomplete="off"></el-input>
            </el-form-item>
            <el-form-item label="商品数量" :label-width="formLabelWidth">
              <el-input v-model="toAddCat.productCount" autocomplete="off" type="number"></el-input>
            </el-form-item>
          </el-form>
          <div slot="footer" class="dialog-footer">
            <el-button @click="addCatDialogFormVisible = false">取 消</el-button>
            <el-button type="primary" @click="saveAddedCat()">确 定</el-button>
          </div>
        </el-dialog>

    <el-dialog title="修改分类" :visible.sync="editCatDialogFormVisible">
      <el-form :model="toEditCat">
        <!--        catId 数据库自动生成-->
        <el-form-item label="分类名称" :label-width="formLabelWidth">
          <el-input v-model="toEditCat.name" autocomplete="off"></el-input>
        </el-form-item>
        <!--       父分类id自动填充  -->
        <!--          层级自动填充-->
        <el-form-item label="父分类" :label-width="formLabelWidth">
          <el-cascader
            v-model="editCatCascaderselectedOptions"
            :options="catTreesCanBeParent"
            :props="cascaderProps"
            @change="handleEditChange"
            :show-all-levels="false"
            expand-trigger="hover"
            change-on-select
            clearable
            disabled="true">
          </el-cascader>
        </el-form-item>
        <el-form-item label="是否显示 [0-不显示，1显示]" :label-width="formLabelWidth">
          <el-input v-model="toEditCat.showStatus" autocomplete="off" type="number" min="0" max="1" ></el-input>
        </el-form-item>
        <el-form-item label="排序" :label-width="formLabelWidth">
          <el-input v-model="toEditCat.sort" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="图标" :label-width="formLabelWidth">
          <el-input v-model="toEditCat.icon" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="计量单位" :label-width="formLabelWidth">
          <el-input v-model="toEditCat.productUnit" autocomplete="off"></el-input>
        </el-form-item>
        <el-form-item label="商品数量" :label-width="formLabelWidth">
          <el-input v-model="toEditCat.productCount" autocomplete="off"></el-input>
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="editCatDialogFormVisible = false">取 消</el-button>
        <el-button type="primary" @click="saveEditedCat()">确 定</el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
export default {
  data() {
    return {
      catTreeDataChanged: false,//拖动导致数据变化,当没有保存,留一个标记位,防止出现一些在数据库和本地数据不一至的情况下操作导致数据出现无法意料的效果
      catTrees: [],
      expandedCats:[],//展开的分类
      defaultProps: {
        children: 'childCats',
        label: 'name'
      },
      updatedCatTrees:[],//批量拖动修改后的数据
      batchDragUpdate: false,//是否批量拖动修改
      treeDraggable: false,//是否可以拖动修改

      batchDelete: false,//是否批量删除
      idsToBatchDeletel: [],

      //新增分类
      toAddCat: {
        "catId": null,
        "catLevel": 1,
        "icon": "图标",
        "name": "分类名字",
        "parentCid": 0,
        "productCount": 0,
        "productUnit": "计量单位",
        "showStatus": 0,
        "sort": 0
      },
      addCatDialogFormVisible: false,
      addCatCascaderselectedOptions: [],

      //编辑修改分类
      toEditCat: {},
      editCatDialogFormVisible: false,
      editCatCascaderselectedOptions: [],

      //级联选择框数据
      catTreesCanBeParent: null,//可以做父分类的分类
      formLabelWidth: '120px',
      cascaderProps: {
        value: "catId",
        children: "childCats",
        label: "name"
      },

    };
  },
  methods: {
    handleDragStart(node, ev) {
      console.log('drag start', node);
    },
    handleDragEnter(draggingNode, dropNode, ev) {
      console.log('tree drag enter: ', dropNode.label);
    },
    handleDragLeave(draggingNode, dropNode, ev) {
      console.log('tree drag leave: ', dropNode.label);
    },
    handleDragOver(draggingNode, dropNode, ev) {
      console.log('tree drag over: ', dropNode.label);
    },
    handleDragEnd(draggingNode, dropNode, dropType, ev) {
      let parentLevel=0;
      let parentId=0;
      if (dropType=="inner"){
        parentLevel=dropNode.data.catLevel;
        parentId=dropNode.data.catId;
      }else {//type=="prev" "next"
        parentLevel=dropNode.data.catLevel-1;
        parentId=dropNode.parentID;
        if (parentId==null){
          parentId=0
        }
      }
      this.catTreeDataChanged=true;
      this.handDragedCatTreeLocal(parentLevel,parentId,draggingNode.data)
      this.updatedCatTrees.push(draggingNode.data)
      if (!this.batchDragUpdate){
        this.updateDragedCatDataPermanent();
      }
    },
    handleDrop(draggingNode, dropNode, dropType, ev) {
      console.log('tree drop: ', dropNode.label, dropType);
    },
    //allow-drop	拖拽时判定目标节点能否被放置。
    // type 参数有三种情况：'prev'、'inner' 和 'next'，
    // 分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
    allowDrop(draggingNode, dropNode, type) {
      let dropNodeLevel=dropNode.data.catLevel;
      let draggingNodeLevel=this.getMaxDeepthOfCatTree(draggingNode.data);
      // console.log("lever=================")
      // console.log(type)
      // console.log(dropNode.data.name)
      // console.log(dropNodeLevel)
      // console.log(draggingNode.data.name)
      // console.log(draggingNodeLevel)
      if (type=="inner"){
        //不变
        console.log("if inner")
      }else {//type=="prev" "next"
        dropNodeLevel--;
      }
      if (dropNodeLevel+draggingNodeLevel<=3){
        return true
      }
      return false;
    },
    //allow-drag	判断节点能否被拖拽
    allowDrag(draggingNode) {
      return true;
    },
    append(node,data) {
      if (this.catTreeDataChanged){
        this.tipToPermanentDrogData();
        return ;
      }else {
        this.getCatCanBeParentTree()
        this.addCatCascaderselectedOptions=[data.catId]
        this.toAddCat.catLevel=data.catLevel+1
        console.log("^^^^^^^^^^^^^^^^^^^^^^^^^^^^666")
        console.log(this.toAddCat.catLevel)
        let fatherNode=node.parent;
        while (fatherNode!=null){
          if (fatherNode.parent!=null){ //不是el-tree的最自动生成的最顶层节点
            console.log("add parent >>",fatherNode)
            this.addCatCascaderselectedOptions.splice(0,0,fatherNode.data.catId)
          }
          fatherNode=fatherNode.parent
        }
        this.addCatDialogFormVisible=true;
      }
    },
    remove(node, data) {
      this.$confirm(`是否确定删除 <strong style="color: brown">${data.name}</strong> 分类及其<strong style="color: brown">所有子分类</strong>？`, '确认信息', {
        distinguishCancelAndClose: true,
        dangerouslyUseHTMLString:true,
        confirmButtonText: '删除',
        cancelButtonText: '取消'
      })
        .then(() => {
          try {
            let ids=[]
            this.delCatByIds(this.getIdsOfCatTree(data,ids))
          }catch(error){
            console.log(error)
            this.openErrorMsgTip("出现运行时错误\n"+error)
          }
        })
        .catch(action => {
          if (action === 'cancel'){
            this.openSuccessMsgTip("取消删除")
          }else {
            console.log(action.assign)
            console.log('删除出错!!')
            this.openErrorMsgTip("删除出错!!")
          }
        });
    },
    editCatNode(node,data){
      if (this.catTreeDataChanged){
        this.tipToPermanentDrogData();
        return ;
      }else {
        this.getCatCanBeParentTree()
        this.toEditCat=data;
        this.editCatCascaderselectedOptions=[data.parentCid]
        let fatherNode=node.parent;
        while (fatherNode!=null){
          if (fatherNode.parent!=null){ //不是el-tree的最自动生成的最顶层节点
            console.log("add parent >>",fatherNode)
            this.editCatCascaderselectedOptions.splice(0,0,fatherNode.data.catId)
          }
          fatherNode=fatherNode.parent
        }
        this.editCatDialogFormVisible=true;
      }
    },

    getProductCatTree() {
      this.$http({
        url: this.$http.adornUrl('/product/pmscategory/tree'),
        method: 'get',
        //params: this.$http.adornParams()
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.catTrees = data.data;
        }
      }).catch(error => {
        console.log(error)
      })
    },
    //判断某个节点是否是最后一个(第三)层级 只有 1 2 3 层
    isNodeInThirdLeve(node,data){
      if (data.catLevel==3){
        return true;
      }
      return false;
    },
    getMaxDeepthOfCatTree(data){
      let deepth=0;
      if (data!=null) {
        deepth=1;
        if (data.childCats!=null){
          let maxChildTreeDeepth=0;
          for(let childNode of  data.childCats){
            let childTreeDeepth=this.getMaxDeepthOfCatTree(childNode)
            if (childTreeDeepth>maxChildTreeDeepth){
              maxChildTreeDeepth=childTreeDeepth;
            }
          }
          deepth+=maxChildTreeDeepth;
        }
      }
      return deepth;
    },
    handDragedCatTreeLocal(parentLevel, parentId, catTreeNodeData){
      if (catTreeNodeData!=null){
        catTreeNodeData.parentCid=parentId
        catTreeNodeData.catLevel=parentLevel+1;
        catTreeNodeData.childCats.forEach(elment=>{
          this.handDragedCatTreeLocal(catTreeNodeData.catLevel,catTreeNodeData.catId,elment)
        })
        // for(let elment in catTreeNodeData.childCats){
        // }
      }
    },
    updateDragedCatDataPermanent(){
      ///product/pmscategory/update/batch
      console.log("permanent ^^^^")
      console.log(this.updatedCatTrees)
      this.$http({
        url: this.$http.adornUrl('/product/pmscategory/update/batch'),
        method: 'post',
        data: this.$http.adornData(this.updatedCatTrees,false)
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.openSuccessMsgTip("更新catetory成功")
          this.updatedCatTrees.clear()
          this.catTreeDataChanged=false
          this.getProductCatTree();//获取更新最新数据
        }
      }).catch(error => {
        console.log(error)
        this.openErrorMsgTip("更新catetory出错了,请您稍后重试,防止更改丢失")
      })
    },
    openSuccessMsgTip(message) {
      this.$notify({
        title: '成功',
        message: message,
        type: 'success'
      });
    },
    openErrorMsgTip(message) {
      this.$notify({
        title: '错误',
        message: message,
        duration: 0,
        type: 'error'
      });
    },

    delCatByIds(catIds){
      this.$http({
        url: this.$http.adornUrl('/product/pmscategory/delete'),
        method: 'delete',
        data: this.$http.adornData(catIds,false),
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.openSuccessMsgTip("删除成功");
          //更新数据
          this.getProductCatTree();
        }
      }).catch(error => {
        console.log(error)
        this.openErrorMsgTip('删除失败');
      })
    },
    getIdsOfCatTree(catNode,ids){
      if (catNode!=null){
        ids.push(catNode.catId)
        if (catNode.childCats!=null&&catNode.childCats.length>0){
          //这种方法无法获取observer动态属性(平常undefin 点击才去获取) 导致数据全是undefine
          // if (childCatNode!=null){
          //   this.getIdsOfCatTree(childCatNode,ids)
          // }
          catNode.childCats.forEach(childCatNode=>{
            if (childCatNode!=null){
              this.getIdsOfCatTree(childCatNode,ids)
            }
          })

        }
        return ids;
      }
    },
    getCatCanBeParentTree(){
      //http://localhost:8086/b2cmall/product/pmscategory/tree/0/2
      this.$http({
        url: this.$http.adornUrl('/product/pmscategory/tree/0/2'),
        method: 'get',
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.catTreesCanBeParent=[{
            "catId": 0,
            "catLevel": 0,
            "icon": "无",
            "name": "无(最顶层分类选择此选项)",
            "parentCid": null,
            "childCats":[],
            "productCount": 0,
            "productUnit": "无",
            "showStatus": 0,
            "sort": 0,
          }];
          this.catTreesCanBeParent.push(...(data.data))
        }
      }).catch(error => {
        console.log(error)
      })
    },
    //TODO
    tipToPermanentDrogData(){
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        this.$message({
          type: 'success',
          message: '删除成功!'
        });
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
      return true;
    },
    //TODO 级联选择变动后的事件处理
    handleEditChange(selectValue){
      this.toEditCat.parentCid=selectValue[selectValue.length-1]
      if (this.toEditCat.parentCid==0){
        this.toEditCat.catLevel=1
      }else {
        //获取父类的level
        this.$http({
          url: this.$http.adornUrl('/product/pmscategory/info/'+this.toEditCat.parentCid),
          method: 'get',
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.toEditCat.catLevel=data.data.catLevel+1
          }else {
            this.openErrorMsgTip("获取父类层级失败")
          }
        }).catch(error => {
          console.log(error)
          this.openErrorMsgTip("获取父类层级失败")
        })
      }
    },
    saveEditedCat(){
      this.handleEditChange(this.editCatCascaderselectedOptions)
      delete this.toEditCat.childCats;
      this.$http({
        url: this.$http.adornUrl('/product/pmscategory/update'),
        method: 'post',
        data: this.$http.adornData(this.toEditCat)
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.openSuccessMsgTip("更新catetory成功")
          //关闭修改窗口
          this.editCatDialogFormVisible=false
          this.getProductCatTree();//获取更新最新数据
        }else {
          this.openErrorMsgTip("更新catetory出错了,请您稍后重试,防止更改丢失")
        }
      }).catch(error => {
        console.log(error)
        this.openErrorMsgTip("更新catetory出错了,请您稍后重试,防止更改丢失")
      })
    },
    saveAddedCat(){
      this.handleAddChange(this.addCatCascaderselectedOptions)
      this.$http({
        url: this.$http.adornUrl('/product/pmscategory/save'),
        method: 'post',
        data: this.$http.adornData(this.toAddCat)
      }).then(({data}) => {
        if (data && data.code === 0) {
          this.openSuccessMsgTip("新增catetory成功")
          //关闭修改窗口
          this.addCatDialogFormVisible=false
          this.getProductCatTree();//获取更新最新数据
        }else {
          this.openErrorMsgTip("新增catetory出错了,请您稍后重试,防止更改丢失")
        }
      }).catch(error => {
        console.log(error)
        this.openErrorMsgTip("新增catetory出错了,请您稍后重试,防止更改丢失")
      })
    },
    handleAddChange(selectValue){
      this.toAddCat.parentCid=selectValue[selectValue.length-1]
      if (this.toAddCat.parentCid==0){
        this.toAddCat.catLevel=1
      }else {
        //获取父类的level
        this.$http({
          url: this.$http.adornUrl('/product/pmscategory/info/'+this.toAddCat.parentCid),
          method: 'get',
        }).then(({data}) => {
          if (data && data.code === 0) {
            this.toAddCat.catLevel=data.data.catLevel+1
          }else {
            this.openErrorMsgTip("获取父类层级失败")
          }
        }).catch(error => {
          console.log(error)
          this.openErrorMsgTip("获取父类层级失败")
        })
      }
    },
    handleCheckChange(data, checked, indeterminate) {
      //该节点所对应的对象、节点本身是否被选中、节点的子树中是否有被选中的节点
      if (this.catTreeDataChanged){
        this.tipToPermanentDrogData()
        return;
      }
      let changedCatIds=[];
      this.getIdsOfCatTree(data,changedCatIds)
      if (checked){
        this.idsToBatchDeletel.push(...changedCatIds)
      }else {
        this.idsToBatchDeletel= this.idsToBatchDeletel.filter(id => !(changedCatIds.includes(id)))
      }
    },
    batchDeleteCatByIds(){
      if (this.catTreeDataChanged){
        this.tipToPermanentDrogData()
        return;
      }
      if (this.idsToBatchDeletel.length>0){
        this
          .$confirm(`是否确定删除所有选中的分类`, '确认信息', {
          distinguishCancelAndClose: true,
          dangerouslyUseHTMLString:true,
          confirmButtonText: '删除',
          cancelButtonText: '取消'
        })
          .then(() => {
            try {
              let idsToDel=this.idsToBatchDeletel;
              this.delCatByIds(idsToDel)
              this.idsToBatchDeletel=[]
            }catch(error){
              console.log(error)
              this.openErrorMsgTip("出现运行时错误\n"+error)
            }
          })
          .catch(action => {
            if (action === 'cancel'){
              this.openSuccessMsgTip("取消删除")
            }else {
              console.log(action.assign)
              console.log('删除出错!!')
              this.openErrorMsgTip("删除出错!!")
            }
          });
      }else {
        this.openSuccessMsgTip("没有要删除的分类")
      }
    },
    cancleDraggedTree(){
      this.$confirm('是否确定放弃所有的拖动修改', '确认信息', {
        distinguishCancelAndClose: true,
        dangerouslyUseHTMLString:true,
        confirmButtonText: '放弃修改',
        cancelButtonText: '保留修改'
      })
        .then(() => {
          this.updatedCatTrees.clear()
          this.catTreeDataChanged=false
          this.openSuccessMsgTip("以删除所有的修改")
          this.getProductCatTree();
        })
        .catch(action => {
          if (action === 'cancel'){
            this.openSuccessMsgTip("保留修改")
          }else {
            console.log(action.assign)
            console.log('运行出错了!!')
            this.openErrorMsgTip("运行出错了!!")
          }
        });
      this.updateDragedCatDataPermanent();
    },
    batchPermanentDraggedCats(){
      if (this.catTreeDataChanged){
        this.updateDragedCatDataPermanent()
      }else {
        this.openSuccessMsgTip("没有已修改的数据")
      }
    },

    //工具 函数
    mapNullArryPropsToEmtyArrayOfTrees(array,props){
      for (let elment in array) {
        if (elment==null){
          delete array[array.indexOf(elment)];
        }else {
          props.forEach(props=>{
            if (elment[props]==null){
              elment[props]=[]
            }else {
              this.mapNullArryPropsToEmtyArrayOfTrees(elment[props],props)
            }
          })
        }
      }
    }
  },

  //生命周期函数
  mounted() {
    this.getProductCatTree();
  }
};
</script>

<style>
.custom-tree-node {
  flex: 1; /* 将 flex 属性修改为 1 */
  display: -webkit-flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
  max-width: 320px; /* 添加 max-width 属性来限制宽度 */
}
.el-col {
  border-radius: 4px;
}
.bg-purple-dark {
  background: #99a9bf;
}
.bg-purple {
  background: #d3dce6;
}
.grid-content {
  border-radius: 4px;
  min-height: 36px;
  text-align: center
}
.row-bg {
  padding: 10px 0;
  background-color: #f9fafc;
}
</style>
